package com.huitone.smspfm.interfacz.core.listener;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.bin.common.utils.ArrayUtils;
import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.interfacz.logger.ExtLogger;

/**   
* @Title ShareMemoryCommandsListener.java 
* @Package com.huitone.smspfm.oldclient.core.listener 
* @Description TODO(用一句话描述该文件做什么) 
* @author ybliang   
* @date 2017年10月12日 上午9:56:20 
* @version V1.0   
*/
public class ShareMemoryCommandsListener extends OutSideCommandsListener {
	
	private static final ExtLogger logger = ExtLogger.create(ShareMemoryCommandsListener.class);
	
	private boolean keepGoing = true;
	
	private long excuteInterval = 10;
	
	private ShareMemoryOpts memoryOpts = null;
	
	private int memorySize = 10240;
	
	private Thread watchDog = null;
	
	@Override
	public void setHandler(OutSideCommandsHandler handler) {
		this.handler = handler;
	}

	public void dispatch(String[] args) {
		
		if (ArrayUtils.isEmpty(args)) return;
		
		if (handler == null) {
			logger.warn("共享内存命令监听器接收到命令:" + Arrays.asList(args) + ",但是监听器并没有配置命令处理类!");
			return;
		}
		
		handler.handle(args);
		
		String command = args[0];
		
		if (StringUtils.equals(command, "start")) {
			handler.start((String[]) ArrayUtils.subarray(args, 1, args.length));
		} else if (StringUtils.equals(command, "reload")) {
			handler.reload((String[]) ArrayUtils.subarray(args, 1, args.length));
		} else if (StringUtils.equals(command, "stop")) {
			handler.stop((String[]) ArrayUtils.subarray(args, 1, args.length));
		}
	}
	
	public String[] parse(String string) {
		
		List<String> params = new ArrayList<>();
		
		while (!StringUtils.isEmpty(string)) {
			
			string = StringUtils.trim(string);
			
			int fromIndex = 0;
			int toIndex = 0;
			boolean startsWith = string.startsWith("\"");
			if (startsWith) {
				fromIndex = 1;
				toIndex = string.indexOf("\"", fromIndex);
			} else {
				fromIndex = 0;
				toIndex = string.indexOf(" ", fromIndex);
			}
			
			if (toIndex == -1) toIndex = string.length();
			
			String param = string.substring(fromIndex, toIndex);
			
			if (!StringUtils.isEmpty(param)) {
				
				params.add(param);
				
				if ((toIndex += 1) > string.length()) 
					toIndex = string.length();
				
				string = string.substring(toIndex);
				
			} else {
				continue;
			}
		}
		
		return params.toArray(new String[]{});
	}
	
	private String getFileName() {
		
		String filename = System.getProperty("ShareMemoryFile");
		if (StringUtils.isEmpty(filename)) {
			filename = System.getenv("ShareMemoryFile");
		}
		
		return filename;
	}
	
	/**
	 * 该方法用于启动监听器
	 */
	public void startListener() {
		
		keepGoing = true;
		
		if (watchDog == null || !watchDog.isAlive()) {
			
			watchDog = new Thread(new Runnable() {
				
				@Override
				public void run() {
					
					String fileName = getFileName();
					
					while(keepGoing) {
						
						if (StringUtils.isEmpty(fileName))
							fileName = getFileName();
						
						if (!StringUtils.isEmpty(fileName)) {
							if (memoryOpts == null) {
								try {
									memoryOpts = new ShareMemoryOpts(fileName, memorySize);
									memoryOpts.reset();
								} catch (IOException e) {
									e.printStackTrace();
								}
							} else {
								try {
									String string = memoryOpts.readThenReset(0, memorySize);
									if (!StringUtils.isEmpty(string)) {
										dispatch(parse(StringUtils.trim(string)));
									}
								} catch (IOException e) {
									e.printStackTrace();
								}
							}
						}
						try {
							TimeUnit.MILLISECONDS.sleep(excuteInterval);
						} catch (InterruptedException e) {}
					}
				}
			});
			watchDog.start();
		} 
		
		handler.start(new String[]{});
		handler.start(new String[]{"lstservice"});
		handler.start(new String[]{"rptservice"});
		handler.start(new String[]{"dlvservice"});
		handler.start(new String[]{"othertasks"});
	}

	/**
	 * 该方法用于停止监听器
	 */
	public void stopListener() {
		
		keepGoing = false;
		
		if (watchDog != null) {
			watchDog.interrupt();
		}
		
		watchDog = null;
	}
}
